<?php
/**
 * A static toolkit to build rail trees in MySQL databases. Create MySQL databases as well.
 *
 **
 * PHP versions 5
 * See http://www.open-rail.org for more informations.
 *
 **
 * Copyright (C)
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of ERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software
 * Fundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
 *
 **
 * @author Bastian Schröder <bastian@open-rail.org>
 * @version 2009-05-18
 * @package rail
 */
class rail_builder {
	
	/**
	 * The current UNIX timestamp.
	 *
	 * @var default_root_passwd
	 */
	public static $default_root_passwd = 'rail';
	
	/**
	 * A prefix string for MySQL tables.
	 *
	 * @var mysql_table_prefix
	 */
	public static $mysql_table_prefix = 'rail_';
	
	/**
	 * The MySQL database connector.
	 *
	 * @var mysqli
	 */
	private static $mysqli = null;
	
	/**
	 * The current UNIX timestamp.
	 *
	 * @var timestamp
	 */
	private static $timestamp = 0;
	

	/**
	 * Function to create new rail_objects easily. Return the rail_id for the new rail_object.
	 * !attention! user and group has to set manualy.
	 *
	 * @param string $pName
	 * @param string $pType type of rail_object
	 * @param int $pEnvironmentId the rail_id from environment
	 * @param bin $pMode mode as binary (9Bit)
	 * @return int
	 */
	private static function made_object ( $pName, $pType, $pEnvironmentId, $pMode ) {
		// create object
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects ( `type`, `environment`, `mode` ) VALUES ('$pType', '$pEnvironmentId', '$pMode')" );
		$data = self::$mysqli->query( "SELECT id FROM " . self::$mysql_table_prefix . "objects WHERE type='$pType' ORDER BY id DESC LIMIT 1" )->fetch_assoc();
		$id = $data[ 'id' ];
		
		// set attributes
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('$id','OBJ_NAME','$pName')" );
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('$id','OBJ_TIME_CREATE','" . self::$timestamp . "')" );
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('$id','OBJ_TIME_LASTWRITE','" . self::$timestamp . "')" );
	
		// return id
		return $id;
	}
	
	
	/**
	 * Function to create new MySSQL table.
	 *
	 * @param string $pName
	 * @param array $pFields MySQL fields
	 */
	private static function made_table ( $pName, $pFields ) {
		self::$mysqli->query( "CREATE TABLE `" . self::$mysql_table_prefix . "$pName` (".
			implode( ',', $pFields ).
			") ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
		);
	}
	
	
	/**
	 * Create a new rail tree.
	 *
	 * @param string $pDatabase MySQL database name
	 * @param string $pUser MySQL user
	 * @param string $pPasswd MySQL password
	 * @param string $pServer MySQL server (optional)
	 */
	public static function make ( $pDatabase, $pUser, $pPasswd, $pServer = 'localhost' ) {
		self::$timestamp = time();

		// connect to mysql server
		self::$mysqli = new mysqli( $pServer, $pUser, $pPasswd );
		if ( mysqli_connect_errno() )
			throw new rail_exception( null, mysqli_connect_error() );
			
		// create database if database dosn't exists
		$data = self::$mysqli->query( "SHOW databases LIKE '$pDatabase'" )->fetch_assoc();
		if( !$data ){
			self::$mysqli->query( "CREATE DATABASE $pDatabase CHARACTER SET utf8" );
			self::$mysqli->select_db( $pDatabase );
		}
		else{
			self::$mysqli->select_db( $pDatabase );
			if ( self::$mysqli->errno )
				throw new rail_exception( null, "Can't access databases: '$pDatabase'" );
		}
		
		// create table objects
		self::made_table( 'objects', array(
			'`id` int(11) NOT NULL AUTO_INCREMENT',
			'`type` varchar(255) NOT NULL',
			'`environment` int(11) NOT NULL',
			'`user` int(11) NOT NULL',
			'`group` int(11) NOT NULL',
			'`mode` varchar(255) NOT NULL',
			'PRIMARY KEY (`id`)',
			'KEY `environment` (`environment`)',
			'KEY `user` (`user`)',
			'KEY `group` (`group`)'
		) );
			
		// create table objects_attributes
		self::made_table( 'objects_attributes', array(
			'`object` int(11) NOT NULL',
			'`attribute` varchar(255) collate utf8_unicode_ci NOT NULL',
			'`value` varchar(255) collate utf8_unicode_ci NOT NULL',
			'KEY `object` (`object`)',
			'KEY `attribute` (`attribute`)'
		) );

		// create table objects_relations
		self::made_table( 'objects_relations', array(
			'`object1` int(11) NOT NULL',
			'`object2` int(11) NOT NULL',
			'`type` varchar(255) collate utf8_unicode_ci NOT NULL',
			'KEY `object1` (`object1`)',
			'KEY `object2` (`object2`)',
			'KEY `type` (`type`)'
		) );

		// create table objects_documents
		self::made_table( 'objects_documents', array(
			'`id` int(11) NOT NULL AUTO_INCREMENT',
			'`md5` varchar(255) COLLATE utf8_unicode_ci NOT NULL',
			'`content` longblob NOT NULL',
			'PRIMARY KEY (`id`)',
			'KEY `md5` (`md5`)'
		) );

		// create table objects_sequences
		self::made_table( 'objects_sequences', array(
			'`id` int(11) NOT NULL AUTO_INCREMENT',
			'`sequence` int(11) NOT NULL',
			'`object` int(11) NOT NULL',
			'`previous` int(11) NOT NULL',
			'`next` int(11) NOT NULL',
			'PRIMARY KEY (`id`)',
			'KEY `object` (`object`)'
		) );
		
		// array of rail_ids
		$rail_id = array();
		
		// create root and .system container
		$rail_id[ 'root' ] = self::made_object ( 'root', RAIL_ROOT, 0, '110110100' );
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('" . $rail_id[ 'root' ] . "','RAIL_VERSION','" . PHPRAIL_VERSION . "-" . PHPRAIL_REVISION . "')" );
		$rail_id[ 'system' ] = self::made_object ( '.system', RAIL_CONTAINER, $rail_id[ 'root' ], '110110100' );

		// create group folder and rail_group root and users
		$rail_id[ 'groups' ] = self::made_object ( 'groups', RAIL_CONTAINER, $rail_id[ 'system' ], '110110100' );
		$rail_id[ 'group_root' ] = self::made_object ( 'root', RAIL_GROUP, $rail_id[ 'groups' ], '110110000' );
		$rail_id[ 'group_users' ] = self::made_object ( 'users', RAIL_GROUP, $rail_id[ 'groups' ], '110100100' );
		
		// create users folder and rail_user root and guest
		$rail_id[ 'users' ] = self::made_object ( 'users', RAIL_CONTAINER, $rail_id[ 'system' ], '110110100' );
		$rail_id[ 'user_root' ] = self::made_object ( 'root', RAIL_USER, $rail_id[ 'users' ], '110100000' );
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('" . $rail_id[ 'user_root' ] . "','RAIL_PASSWD','" . md5( self::$default_root_passwd ) . "')" );
		$rail_id[ 'user_guest' ] = self::made_object ( 'guest', RAIL_USER, $rail_id[ 'users' ], '110100100' );
		self::$mysqli->query( "INSERT INTO " . self::$mysql_table_prefix . "objects_attributes (`object`,`attribute`,`value`) VALUES ('" . $rail_id[ 'user_guest' ] . "','RAIL_PASSWD','" . md5( 'guest' ) . "')" );
		self::$mysqli->query( "UPDATE " . self::$mysql_table_prefix . "objects SET `user`='" . $rail_id[ 'user_guest' ] . "', `group`='" . $rail_id[ 'group_users' ] . "' WHERE `id`='" . $rail_id[ 'user_guest' ] . "'" );
		// set user and group attribute
		self::$mysqli->query( "UPDATE " . self::$mysql_table_prefix . "objects SET `user`='" . $rail_id[ 'user_root' ] . "', `group`='" . $rail_id[ 'group_root' ]  . "' WHERE `user`='0'" );
	}
	

	/**
	 * Change the password for the rail_user named root
	 *
	 * @param string $pDatabase MySQL database name
	 * @param string $pUser MySQL user
	 * @param string $pPasswd MySQL password
	 * @param string $pServer MySQL server (optional)
	 */
	public static function reset_root_passwd ( $pDatabase, $pUser, $pPasswd, $pServer = 'localhost' ) {
		// connect to mysql server
		self::$mysqli = new mysqli( $pServer, $pUser, $pPasswd );
		if ( mysqli_connect_errno() )
			throw new rail_exception( null, mysqli_connect_error() );
			
		// create database if database dosn't exists
		self::$mysqli->select_db( $pDatabase );
		if ( self::$mysqli->errno )
			throw new rail_exception( null, "Can't access databases: '$pDatabase'" );
		
		// get rail_id for rail_user named root
		$data = self::$mysqli->query( "
			SELECT
				" . self::$mysql_table_prefix . "objects.id
			FROM
				" . self::$mysql_table_prefix . "objects,
				" . self::$mysql_table_prefix . "objects_attributes
			WHERE
				" . self::$mysql_table_prefix . "objects.id=" . self::$mysql_table_prefix . "objects_attributes.object AND
				" . self::$mysql_table_prefix . "objects.type='RAIL_USER' AND
				" . self::$mysql_table_prefix . "objects_attributes.value='root'
			LIMIT
				1"
		)->fetch_assoc();
		$id = $data[ 'id' ];

		// update root passwd
		self::$mysqli->query( "
			UPDATE
				" . self::$mysql_table_prefix . "objects_attributes
			SET
				`value`='" . md5( self::$default_root_passwd ) . "'
			WHERE 
				`object`='$id' AND
				`attribute`='RAIL_PASSWD'
			LIMIT
				1"
		);
	}

} // End of rail_builder
?>